home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / haeberli / libgutil / getfile.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  8KB  |  332 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17.  
  18. #include <unistd.h>
  19. #include <sys/types.h>
  20. #include <sys/socket.h>
  21. #include <signal.h>
  22. #include <sys/fcntl.h>
  23. #include <sys/errno.h>
  24. #include <sys/time.h>
  25. #include <errno.h>
  26. #include <sys/stat.h>
  27. #include <netinet/in.h>
  28. #include <netdb.h>
  29. #include <device.h>
  30. #include <gl.h>
  31. #include <ctype.h>
  32. #ifdef __cplusplus
  33. #include <osfcn.h>
  34. #endif /* __cplusplus */
  35. #include <stdio.h>
  36. #include <strings.h>
  37. #ifdef __cplusplus
  38. #include <libc.h>
  39. #include <malloc.h>
  40. #endif /* __cplusplus */
  41.  
  42. #define GIZMO_DIRECTORY "/usr/lib/showcase/"
  43.  
  44. static browsefd, childpid, browsegizmodead;
  45. static long oldshowcase = -1;
  46.  
  47. static void errormessage(char *s)
  48. {
  49.     fprintf(stderr, "%s\n", s);
  50. }
  51.  
  52. /* for browsegizmo, call this as:
  53.  *
  54.  *    doexec("browsegizmo", xctr, yctr, file, dir, 0);
  55.  *
  56.  */
  57.  
  58. /*VARARGS*/
  59. static int doexec(char *s, char *xctr, char *yctr,
  60.        char *file, char *dir)
  61. {
  62.     struct    sockaddr_in saddr;
  63.     int        sock1, len, child, fd;
  64.     char    *gargv[20];
  65.     char    charportnum[200], gizmopath[100];
  66.     struct    stat statbuf;
  67.  
  68.  
  69.     /* Create a socket for accepting the connection. */
  70.  
  71.     if (stat(s,&statbuf) < 0)
  72.     sprintf(gizmopath, "%s%s", GIZMO_DIRECTORY, s);
  73.     else
  74.     sprintf(gizmopath, "./%s", s);
  75.     sock1 = socket(AF_INET, SOCK_STREAM, 0);
  76.     if(sock1 < 0) {
  77.     /*perror("error opening socket");*/
  78.     errormessage("Error opening gizmo.");
  79.     return 0;
  80.     }
  81.  
  82.     /* Create name for parent socket on local machine. */
  83.  
  84.     saddr.sin_family = AF_INET;
  85.     saddr.sin_addr.s_addr = INADDR_ANY;
  86.     saddr.sin_port = 0;
  87.     if(bind(sock1, &saddr, sizeof(saddr))) {
  88.     /*perror("binding parent socket");*/
  89.     close(sock1);
  90.     errormessage("Error opening gizmo.");
  91.     return 0;
  92.     }
  93.  
  94.     /* Find out port number assigned to parent socket. */
  95.  
  96.     len = sizeof(saddr);
  97.     if(getsockname(sock1, &saddr, &len)) {
  98.     /*perror("getting parent socket name");*/
  99.     close(sock1);
  100.     errormessage("Error opening gizmo.");
  101.     return 0;
  102.     }
  103.  
  104.     listen(sock1, 1 /* max size of queue of waiting connectors */);
  105.     child = fork();
  106.     if(child) {
  107. retry:
  108.     fd = accept(sock1, 0, 0);
  109.     if(fd == -1) {
  110.         if (errno == EINTR)
  111.         goto retry;
  112.         sprintf(charportnum, "Failed to open gizmo.\nError %d", errno);
  113.         errormessage(charportnum);
  114.         kill(child,SIGKILL);
  115.         return 0;
  116.     }
  117.     browsefd = fd;
  118.     childpid = child;
  119.     close(sock1);
  120.     return 1;
  121.     } else {
  122.     /*sginap(2);*/
  123.     close(sock1);
  124.     sprintf(charportnum, "%d", ntohs(saddr.sin_port));
  125.     gargv[0] = gizmopath;
  126.     gargv[1] = charportnum;
  127.     gargv[2] = "4";
  128.     gargv[3] = xctr;
  129.     gargv[4] = yctr;
  130.     gargv[5] = oldshowcase ? "1" : file;
  131.     gargv[6] = oldshowcase ? file : dir;
  132.     gargv[7] = oldshowcase ? dir : 0;
  133.     gargv[8] = 0;
  134.     execvp(gizmopath, gargv);
  135.     perror("exec failed");
  136.     exit(1);
  137.     }
  138. }
  139.  
  140. static int readbuf(int fd, char *p, int totbytes)
  141. {
  142.     int nbytes, n;
  143.  
  144.     nbytes = 0;
  145.     while (nbytes < totbytes) {
  146.     if ( (n=read(fd,p+nbytes,totbytes-nbytes)) < 0) {
  147.         if (errno == EINTR) continue;
  148.         /*perror("Showcase read failure");*/
  149.         return -1;
  150.     }
  151.     nbytes += n;
  152.     }
  153.     return nbytes;
  154. }
  155.  
  156. static void readfromgizmo(char *buf, int nbytes)
  157. {
  158.     if(readbuf(browsefd,buf,nbytes)<0){
  159.     errormessage("Can't read from gizmo");
  160.     kill(childpid,SIGKILL);
  161.     }
  162. }
  163.     
  164. static void senddevtogizmo(long data)
  165. {
  166.     write(browsefd,&data,sizeof(data));
  167. }
  168.  
  169. static void sendgizmo(long data)
  170. {
  171.     write(browsefd,&data,sizeof(data));
  172. }
  173.  
  174. #define ABORT        20002
  175. #define DIRNAMEDEV    20094
  176. #define FILENAMEDEV    20082
  177. #define NUKEFILENAMEDEV    20083
  178. #define POKEGIZMO    20086
  179. #define GIZMOINITEND    20136
  180. #define DEADGIZMO    29999
  181.  
  182. static int halfbakedqread(int *val)
  183. {
  184.     long    n;
  185.     fd_set    fdset;
  186.     int        buf[2];
  187.     struct timeval    timeout, *tp = &timeout;
  188.  
  189.     while(1) {
  190. tryagain:
  191.     if (browsegizmodead) {
  192.         *val = 0; return DEADGIZMO;
  193.     }
  194.     FD_ZERO(&fdset);
  195.     FD_SET(browsefd, &fdset);
  196.     tp = 0;
  197.     if ((n = select(FD_SETSIZE, &fdset, 0, 0, tp)) < 0) {
  198.         if (errno == EINTR)    {
  199.         goto tryagain;
  200.         }
  201.         /*perror("select");*/
  202.         errormessage("Select error");
  203.         *val = 0;
  204.         return ABORT;
  205.     }
  206.     if(FD_ISSET(browsefd, &fdset)) {
  207.         if((n = readbuf(browsefd, (char *)buf, sizeof(buf))) < 0) {
  208.         /*perror("Showcase reading stream message");*/
  209.         errormessage("Gizmo read error");
  210.         kill(childpid,SIGKILL);
  211.         }
  212.         if (n == 0)
  213.         continue;
  214.         *val = buf[1];
  215.         return buf[0];
  216.     }
  217.     }
  218. }
  219.  
  220. void getfilename(char *title, char *str, char *dir, long cx, long cy)
  221. {
  222.     char    *s;
  223.     int        dev, val;
  224.     char    xctr[10], yctr[10];
  225.     char        *tmpdir, *tmpfilename;
  226.     struct    stat statbuf;
  227.     mode_t      omask;
  228.  
  229.     if (oldshowcase == -1) {
  230.     if (stat("/usr/lib/showcase/audiogizmo", &statbuf) < 0)
  231.         oldshowcase = 1;
  232.     else
  233.         oldshowcase = 0;
  234.     }
  235.     *str = 0;
  236.     if (cx < 200) cx = 200;
  237.     if (cx > XMAXSCREEN - 200) cx = XMAXSCREEN - 200;
  238.     if (cy < 300) cy = 300;
  239.     if (cy > YMAXSCREEN - 300) cy = YMAXSCREEN - 300;
  240.     if (oldshowcase==0) { cx -= 150; cy -= 200; }
  241.     sprintf(xctr, "%d", cx);
  242.     sprintf(yctr, "%d", cy);
  243.  
  244.     tmpdir = (char *)getenv("TMPDIR");
  245.     if (tmpdir == 0) {
  246.         tmpfilename = (char *)malloc(20);
  247.         strcpy(tmpfilename, "/tmp/showcase_tmp");
  248.     } else {
  249.         tmpfilename = (char *)malloc(strlen(tmpdir) + 20);
  250.     strcpy(tmpfilename, tmpdir);
  251.         strcat(tmpfilename,"/showcase_tmp");
  252.     }
  253.     omask = umask(0);
  254.     mkdir (tmpfilename,0777);
  255.     mkdir ("/usr/tmp/showcase_tmp",0777);
  256.     umask(omask);
  257.     free(tmpfilename);
  258.     if (!(doexec("browsegizmo", xctr, yctr, title, dir)))
  259.         return;
  260.     senddevtogizmo(GIZMOINITEND);
  261.     browsegizmodead = 0;
  262.     while (1) {
  263.     dev = halfbakedqread(&val);
  264.     switch (dev) {
  265.         case DIRNAMEDEV:
  266.                 readfromgizmo(dir, val);
  267.                 break;
  268.         case FILENAMEDEV:
  269.                 readfromgizmo(str, val);
  270.             senddevtogizmo(ABORT);
  271.             senddevtogizmo(0);
  272.                 return;
  273.         case NUKEFILENAMEDEV:
  274.                 s = (char *)malloc(val);
  275.                 readfromgizmo(s, val);
  276.                 free(s);
  277.                 break;
  278.         case ABORT:
  279.                 senddevtogizmo(ABORT);
  280.             senddevtogizmo(0);
  281.             qreset();
  282.                 return;
  283.         case DEADGIZMO:
  284.             *str = 0; *dir = 0;
  285.             qreset();
  286.             return;
  287.             default:
  288.             sendgizmo(POKEGIZMO);
  289.                 break;
  290.     }
  291.     }
  292. }
  293.  
  294. static void catchsignal(int sig)
  295. {
  296.     long giz;
  297.  
  298.     switch(sig) {
  299.     case SIGCLD:
  300.         giz = wait(0);
  301.         if (giz == childpid) {
  302.         childpid = 0;
  303.         browsegizmodead = 1;
  304.         }
  305.         break;
  306.     case SIGILL:
  307.         fprintf(stderr, "SIGILL signal\n");
  308.         goto savefile;
  309.     case SIGQUIT:
  310.         fprintf(stderr, "SIGQUIT signal\n");
  311.         goto savefile;
  312.     case SIGTERM:
  313.         fprintf(stderr, "SIGTERM signal\n");
  314.         goto savefile;
  315.     case SIGIOT:
  316.         fprintf(stderr, "SIGIOT signal\n");
  317.         break;
  318.     case SIGIO:
  319.         fprintf(stderr, "SIGIO signal\n");
  320.         break;
  321.     case SIGPIPE:
  322.         fprintf(stderr, "SIGPIPE!\n");
  323.         break;
  324.     default:
  325.         fprintf(stderr, "Unknown signal %d\n", sig);
  326. savefile:
  327.         exit(1);
  328.     }
  329.     signal(sig, catchsignal);
  330.     return;
  331. }
  332.